home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
ZED3DSRC.ZIP
/
DRAWPOLY.H
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-22
|
5KB
|
141 lines
#ifndef __POLYDRAW_H
#define __POLYDRAW_H
#ifdef __cplusplus
extern "C" {
#endif
/***********************************************************************
*
* Polygon drawing routines
* (C) 1995 by Sébastien Loisel - All Rights Reserved
*
***********************************************************************/
/* These routines need a few special macros to work, which are defined
hereafter. These macros convert from outbuffer space to projection
plane space and vice-versa. The following macros are general purpose.
The catch is this: if you're certain that the outbuffer is of a specific,
power-of-two width, then you could replace the expensive mul/divs by
shifts, and speed up things a bit. These are used extensively, once
per scanline per edge. Anywhere these macros are used, the outbuffer is
available as out, a pointer to an outbuffer. Assume fixed point as
mentionned above. Note that the buffer should span -1 through +1 in
projection plane coords */
#define bufx2proj(x) (((x)<<8)/out->maxx)
#define bufy2proj(y) (((y)<<8)/out->maxy)
#define proj2bufx(x) (((x)*out->maxx)>>8)
#define proj2bufy(y) (((y)*out->maxy)>>8)
/* the next one is similar to the above, except it's meant to multiply
by buffer width */
#define mulwidth(y) ((y)*out->width)
/* Define here the type used for pixels */
typedef unsigned char pixel;
struct edge_struct;
typedef struct edge_struct edge;
struct edge_struct
{
long x1,y1;
/* The rest is for internal use only */
long x2,y2;
edge *next;
long intercept; /* current x or y intercept */
long numerator,denominator; /* fraction part of slope */
long increment; /* integer part of slope */
long run; /* running total of slope */
};
struct polygon_struct
{
/* The following is initialized by the caller, not the library */
long numedges; /* number of edges in array */
edge *edgetable; /* edge ARRAY!!! not list */
long A,B,C,D; /* plane equation parameters Ax+By+Cz=D */
long color; /* color for flat shading duh huh */
/* The following is used internally by the library */
edge inactive; /* inactive edge table */
edge active; /* active edge table */
long nextremove; /* next scanline at which we'll remove edges from active */
};
/* special note:
The edge table should list all of the polygon's points as
x1 and y1 entries, in a continuous fashion. That is,
using a loop of the form for(a=0;a<numedges;a++) and looking
at edgetable[a].x1 and edgetable[a].y1 will take you around the
polygon. The entries x2 and y2 will be initialized internally later,
you do not need to initialize them */
typedef struct polygon_struct polygon;
struct outbuffer_struct
{
long width, height; /* buffer width and height */
long maxx,maxy; /* Maximum coordinate value in absolute value. That is,
the buffer coordinates are in [-maxx,maxx] and
[-maxy,maxy]. */
pixel *buffer; /* pointer to linear buffer */
};
typedef struct outbuffer_struct outbuffer;
void drawpolygon(polygon *poly, outbuffer *out);
/* draws poly on output buffer out */
outbuffer *allocbuf(long maxy, long maxx);
/* allocates & initializes an outbuffer. returns 0 on error, otherwise
returns initialized outbuffer (pointer to). The buffer allocated has
a width of (maxx*2)+2 (+1 for origin, +1 so it comes to a multiple of 2).
Height is left untouched per se, but an extra line is allocated so the
global allocation is a multiple of 4 elements. */
void destroybuf(outbuffer *out);
/* deallocates outbuffer and members buffer and zbuffer, overwriting them
with null pointers, hoping to ensure a crash if out is used afterwards */
/* Internal functions follow */
/* Functions preceded by a h_ are meant to be used in a horizontal scan-line
algorithm, while those precede by a v_ are meant to be used in a vertical
scan-line algo, those without a prefix are invariable (can be used in
either algo) */
void init_edges(polygon *poly, outbuffer *out);
/* Calculates edge data, but don't sort yet, also inits poly->nextremove */
void sort_edges(polygon *poly, outbuffer *out);
/* Builds inactive edge table, properly sorted - if inactive->next is
0, then no polygon should be drawn */
void update_lists(polygon *poly, long scanline);
/* Updates active & inactive lists for scanline - if after calling this,
poly->active.next is zero, we're done drawing the polygon */
void update_intercept(polygon *poly);
/* Update intercept value for edges in active list */
void draw_spans(polygon *poly, outbuffer *out, long delta);
/* Draws all spans to outbuffer */
#ifdef __cplusplus
}
#endif
#endif